package common

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"reflect"
	"time"

	"github.com/bwmarrin/snowflake"
)

//CreateInstance 创建一个实例的指针
func CreateInstance(i interface{}) (interface{}, error) {
	atype := reflect.TypeOf(i)
	if atype.Kind() == reflect.Ptr {
		typei := reflect.TypeOf(i).Elem()
		objNew := reflect.New(typei)
		objNewInterface := objNew.Interface()
		return objNewInterface, nil
	}

	return nil, errors.New("type not support only support ptr")

}

//CreateSlice 创建一个slice
func CreateSlice(i interface{}) interface{} {
	typei := reflect.TypeOf(i).Elem()
	typea := reflect.SliceOf(typei)

	result := reflect.MakeSlice(typea, 0, 1)
	fmt.Println("****************", typei, typea, result.Kind())
	return result
}

var node *snowflake.Node

//func init() {
//SetSnowflakeParam(1, 1620574027000, 5, 7)
//}

//SetSnowflakeNodeID 设置nodeid等参数
func SetSnowflakeParam(nid int64, epoch int64, nodebits uint8, stepbits uint8) error {
	if nid > 512 {
		return errors.New("node is too large")
	}
	snowflake.Epoch = epoch       //1620574027000
	snowflake.NodeBits = nodebits //5
	snowflake.StepBits = stepbits //7
	var err error
	node, err = snowflake.NewNode(nid)
	return err
}

var defaultNode *snowflake.Node

func init() {
	snowflake.Epoch = time.Now().Unix() * 1000
	snowflake.NodeBits = 5
	snowflake.StepBits = 17
	//var err error
	defaultNode, _ = snowflake.NewNode(1)
}

//
func GetSnowflakeIdDefualtID() (int64, error) {
	if defaultNode != nil {
		return defaultNode.Generate().Int64(), nil
	}
	return 0, errors.New("node is nil")

}

// GetSnowflakeId 获取id 1620574027000 为2021.5.9时间戳
func GetSnowflakeId() (int64, error) {
	if node == nil {
		err := SetSnowflakeParam(1, 1620574027000, 5, 7)
		if err != nil {
			return 0, err
		}
	}
	if node != nil {
		return node.Generate().Int64(), nil
	}
	return 0, errors.New("node is nil")

}

func HttpGet(url string) ([]byte, error) {
	resp := make([]byte, 0)
	ctx, _ := context.WithTimeout(context.Background(), time.Second*2)
	done := make(chan error, 1)
	go func() {
		httpResp, err := http.Get(url)
		defer httpResp.Body.Close()
		if err != nil {
			done <- err
		}
		resp, err = ioutil.ReadAll(httpResp.Body)
		done <- err
	}()
	select {
	case err := <-done:
		return append([]byte{}, resp...), err
	case <-ctx.Done():
		return resp, nil
	}
}

func GetGaudMapCode(key, keywords, subdistrict string) (map[string]interface{}, error) {
	reqValue := &url.Values{}
	reqValue.Set("key", key)
	reqValue.Set("keywords", keywords)
	reqValue.Set("subdistrict", subdistrict)
	reqUrl := "https://restapi.amap.com/v3/config/district" + "?" + reqValue.Encode()
	respData := make(map[string]interface{})
	b, err := HttpGet(reqUrl)
	if err != nil {
		return respData, err
	}
	err = json.Unmarshal(b, &respData)
	if err != nil {
		return respData, err
	}
	return respData, err
}
